﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Enferno.Public.InversionOfControl;
using Enferno.Public.Web.Mappers.Resolvers;
using Enferno.Public.Web.Models;
using Enferno.StormApiClient.Products;
using Enferno.Web.StormUtils;

namespace Enferno.Public.Web.Mappers.ProductProfiles
{
    public class ProductToVariantModelProfile :
        ProductToCustomVariantModelProfile<VariantModel>
    {
        
    }

    public class ProductToCustomVariantModelProfile<TVariantModel> : ProductToVariantBaseModelProfile<TVariantModel, OnHandStatusModel, PriceModel, ProductFileModel, ProductManufacturerModel,
                ProductListCustomVariantModel<TVariantModel, ProductItemCustomVariantModel<TVariantModel>>, ProductItemCustomVariantModel<TVariantModel>, FilterModel, ParametricModel, ParametricValueModel>
        where TVariantModel : VariantBaseModel<OnHandStatusModel, PriceModel, ProductFileModel, ParametricModel, ParametricValueModel> { }

    public class ProductToVariantBaseModelProfile<
        TVariantModel, 
        TOnHandStatusModel, 
        TPriceModel, 
        TProductFileModel, 
        TProductManufacturerModel, 
        TProductListModel, 
        TProductItemModel, 
        TFilterModel, 
        TParametricModel, 
        TParametricValueModel> : Profile
        where TVariantModel : VariantBaseModel<TOnHandStatusModel, TPriceModel, TProductFileModel, TParametricModel, TParametricValueModel>
        where TOnHandStatusModel : OnHandStatusModel, new()
        where TPriceModel : PriceModel, new()
        where TProductFileModel : ProductFileModel, new()
        where TParametricModel : ParametricBaseModel<TParametricValueModel>
        where TParametricValueModel : ParametricValueModel
        where TProductManufacturerModel : ProductManufacturerModel
        where TProductListModel : ProductListBaseModel<TProductItemModel, TFilterModel, TVariantModel, TProductFileModel, TProductManufacturerModel, TPriceModel, TOnHandStatusModel, TParametricModel, TParametricValueModel>
        where TProductItemModel : ProductItemBaseModel<TVariantModel, TProductFileModel, TProductManufacturerModel, TPriceModel, TOnHandStatusModel, TParametricModel, TParametricValueModel>
        where TFilterModel : FilterModel
    {
        protected IMappingExpression<Product, TVariantModel> Mapping { get; set; } 

        protected override void Configure()
        {
            var mapping = Mapping ?? Mapper.CreateMap<Product, TVariantModel>();

            mapping
                .ForMember(to => to.ManufacturePartNo, opts => opts.MapFrom(from => from.Manufacturer.PartNo))
                .ForMember(to => to.Name, opts => opts.MapFrom(from => from.VariantName))
                .ForMember(to => to.Price, opts => opts.ResolveUsing<ProductPriceResolver<TPriceModel>>())
                .ForMember(to => to.Flags, opts => opts.ResolveUsing<ProductFlagsResolver>())
                .ForMember(to => to.Files, opts => opts.ResolveUsing<VariantFilesResolver<TProductFileModel>>())
                .ForMember(to => to.ImageKey, opts => opts.MapFrom(from => from.ImageKey.ToString()))
                .ForMember(to => to.ImageUrl,
                    opts =>
                        opts.ResolveUsing(
                            from => from.ImageKey.HasValue ? Link.ImageUrl(from.ImageKey.ToString()) : null))
                .ForMember(to => to.OnHandStatus, opts => opts.ResolveUsing<ProductOnHandStatusResolver<TOnHandStatusModel>>())
                .ForMember(to => to.VariantParametrics, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.Parametrics, opts => opts.Ignore());
        }
    }
}
